Skip to content

使用 Docker Compose 安裝 Elasticsearch 與 Kibana

TLDR

  • 透過 docker-compose.yml 部署單節點 Elasticsearch 與 Kibana 環境。
  • 必須設定 volumes/elasticsearch/data 的擁有者為 UID 1000,否則容器將因權限不足無法啟動。
  • 建議不掛載 logs 目錄,以避免升級時因權限問題導致啟動失敗。
  • 使用 setup 容器透過 API 自動設定 kibana_system 使用者密碼,解決預設密碼隨機產生的問題。
  • 透過 bootstrap.memory_lock=trueulimits 設定,防止 JVM Heap 被交換至磁碟。
  • 建議 JVM Heap 大小設定為實體記憶體的 50% 左右,並透過 MEM_LIMIT 限制容器記憶體使用量。

環境設定與權限管理

在部署 Elasticsearch 容器時,最常見的問題是資料目錄的權限不足。由於 Elasticsearch 容器內部的執行使用者 ID 為 1000,若宿主機的目錄權限不符,服務將無法寫入資料。

建立資料目錄

請在專案目錄下執行以下指令,確保資料目錄具備正確的權限:

bash
# 建立資料目錄
mkdir -p volumes/elasticsearch/data

# 設定權限 (1000 是 Elasticsearch 容器內的使用者 ID)
sudo chown -R 1000:1000 volumes

TIP

建議不要掛載 logs 目錄。在升級或遷移 Elasticsearch 時,log 檔案的權限變更經常導致容器啟動失敗。此外,Kibana 本身不儲存持久化資料,因此無需建立 data volume。

設定檔案

環境變數設定 (.env)

透過 .env 檔案集中管理版本與密碼設定:

env
# Password for the 'elastic' user (至少 6 個字元)
ELASTIC_PASSWORD=YourPassword

# Password for the 'kibana_system' user (至少 6 個字元)
KIBANA_PASSWORD=Wing1205

# Version of Elastic products
STACK_VERSION=9.1.4

# Set the cluster name
CLUSTER_NAME=docker-cluster

# Set to 'basic' or 'trial' to automatically start the 30-day trial
LICENSE=basic

# Port to expose Elasticsearch HTTP API to the host
ES_PORT=9200

# Port to expose Kibana to the host
KIBANA_PORT=5601

# Increase or decrease based on the available host memory (in bytes)
# 1GB = 1073741824 bytes
MEM_LIMIT=2147483648

Docker Compose 設定

使用 docker-compose.yml 定義服務,並加入 setup 容器進行自動化初始化:

yaml
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    container_name: elasticsearch
    restart: always
    environment:
      - node.name=elasticsearch
      - cluster.name=${CLUSTER_NAME}
      - discovery.type=single-node
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=false
      - xpack.security.transport.ssl.enabled=false
      - xpack.license.self_generated.type=${LICENSE}
      - ES_JAVA_OPTS=-Xms512m -Xmx512m -Xlog:gc:stdout:time,level,tags
    volumes:
      - ./volumes/elasticsearch/data:/usr/share/elasticsearch/data
    ports:
      - ${ES_PORT}:9200
    mem_limit: ${MEM_LIMIT}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test: ["CMD-SHELL", "curl -s -u elastic:${ELASTIC_PASSWORD} http://localhost:9200/_cluster/health | grep -q 'yellow\\|green'"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s

  kibana:
    depends_on:
      elasticsearch:
        condition: service_healthy
    image: docker.elastic.co/kibana/kibana:${STACK_VERSION}
    container_name: kibana
    restart: always
    environment:
      - SERVER_NAME=kibana
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}
    ports:
      - ${KIBANA_PORT}:5601
    mem_limit: ${MEM_LIMIT}
    healthcheck:
      test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s

  setup:
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    container_name: elasticsearch-setup
    user: "0"
    command: >
      bash -c '
        echo "等待 Elasticsearch 啟動...";
        until curl -s -u elastic:${ELASTIC_PASSWORD} http://elasticsearch:9200/_cluster/health?pretty | grep -q "yellow\|green"; do
          echo "Elasticsearch 尚未就緒,等待中...";
          sleep 10;
        done;
        echo "設定 kibana_system 使用者密碼...";
        curl -s -X POST -u elastic:${ELASTIC_PASSWORD} -H "Content-Type: application/json" \
          http://elasticsearch:9200/_security/user/kibana_system/_password \
          -d "{\"password\":\"${KIBANA_PASSWORD}\"}";
        echo "初始化完成!";
      '
    depends_on:
      elasticsearch:
        condition: service_healthy

常見問題排除

記憶體不足

當容器啟動失敗或效能低落時,通常是記憶體配置問題。

  • 情境:主機記憶體資源不足,導致 JVM 無法啟動。
  • 解法:調整 .env 中的 MEM_LIMIT,並確保 ES_JAVA_OPTS 中的 Heap 設定(-Xms-Xmx)約為主機記憶體的 50%。

權限錯誤

  • 情境:容器啟動後立即停止,查看 Log 顯示 Permission denied
  • 解法:確認 volumes/elasticsearch/data 的擁有者為 UID 1000。若在開發環境中仍無法解決,可暫時使用 sudo chmod -R 777 volumes/elasticsearch/data 進行測試。

異動歷程

    • 初版文件建立。
    • 修正 YAML 檔遺漏 restart 設定導致重開機會自動啟動之問題。